package com.bes.bessdk.utils;

import android.os.Handler;
import android.os.HandlerThread;
import android.text.TextUtils;
import android.text.format.DateFormat;
import android.util.Log;

import com.bes.sdk.core.OtaLog;

import java.io.BufferedWriter;
import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import java.io.PrintWriter;
import java.io.StringWriter;
import java.io.Writer;

/**
 * Log工具类，具备打印规则控制，打印并保存本地文件等操作
 */
public class LogUtils
{
	static String PROJECT_OTA = "ota.txt" ;
	static String PROJECT_LOG = "Log.txt" ;
	static String PROJECT_HW_CLOUD_LOG = "HwCloudLog.txt" ;
	static boolean V_DEBUG = true;
	static boolean I_DEBUG = true;
	static boolean E_DEBUG = true;
	static boolean W_DEBUG = true;

	private static void checkBetaOrLine(){
		V_DEBUG = true;
		I_DEBUG = true;
		E_DEBUG = true;
		W_DEBUG = true;

	}
	
	/**
	 * 初始化程序log打印规则
	 * @param v_log : true 使能 v 等级log ; false 关闭 v 等级log
	 * @param i_log : true 使能 i 等级log ; false 关闭 i 等级log
	 * @param e_log : true 使能 e 等级log ; false 关闭 e 等级log
	 */
	public static void InitLogUtils(boolean w_log ,boolean v_log, boolean i_log, boolean e_log)
	{
		V_DEBUG = v_log ;
		I_DEBUG = i_log ;
		E_DEBUG = e_log ;
		W_DEBUG = w_log ; 
	}
	
	public static void v(String tag, String msg)
	{
		checkBetaOrLine();
		if (V_DEBUG && msg != null)
		{
			Log.v(tag, msg);
		}
			
	}
	
	public static void v_write(String tag, String msg)
	{
		checkBetaOrLine();
		if (V_DEBUG && msg != null)
		{
			Log.v(tag, msg);
			FileUtils.writeTOfileAndActiveClear(PROJECT_LOG,
						DateFormat.format("yyyy-MM-dd HH:mm:ss", System.currentTimeMillis()) + "V<" + tag + ">---" + msg);
        }	
	}

	public static void v(String tag, String msg, Throwable t)
	{
		checkBetaOrLine();
		if (V_DEBUG && msg != null)
		{
			Log.v(tag, msg, t);
		}
			
    }
	
	public static void v_write(String tag, String msg, Throwable t)
	{
		checkBetaOrLine();
		if (V_DEBUG && msg != null)
		{
			Log.v(tag, msg, t);
			FileUtils.writeTOfileAndActiveClear(PROJECT_LOG,
					DateFormat.format("yyyy-MM-dd HH:mm:ss", System.currentTimeMillis()) + "Vt<" + tag + ">---" + msg);
		}
			
	}
	public static void w(String tag, String msg)
	{
		checkBetaOrLine();
		if (V_DEBUG && msg != null)
		{
			Log.w(tag, msg);
		}
			
	}
	
	public static void w_write(String tag, String msg)
	{
		checkBetaOrLine();
		if (V_DEBUG && msg != null)
		{
			Log.w(tag, msg);
			FileUtils.writeTOfileAndActiveClear(PROJECT_LOG,
						DateFormat.format("yyyy-MM-dd HH:mm:ss", System.currentTimeMillis()) + "V<" + tag + ">---" + msg);
        }	
	}

	public static void w(String tag, String msg, Throwable t)
	{
		checkBetaOrLine();
		if (V_DEBUG && msg != null)
		{
			Log.w(tag, msg, t);
		}
			
    }
	
	public static void w_write(String tag, String msg, Throwable t)
	{
		checkBetaOrLine();
		if (V_DEBUG && msg != null)
		{
			Log.w(tag, msg, t);
			FileUtils.writeTOfileAndActiveClear(PROJECT_LOG,
					DateFormat.format("yyyy-MM-dd HH:mm:ss", System.currentTimeMillis()) + "Vt<" + tag + ">---" + msg);
		}
			
	}
	
	public static void i(String tag, String msg)
	{
		checkBetaOrLine();
		if (V_DEBUG && msg != null)
		{
			Log.i(tag, msg);
		}
			
	}
	
	public static void i_write(String tag, String msg)
	{
		checkBetaOrLine();
		if (V_DEBUG && msg != null)
		{
			Log.v(tag, msg);
			FileUtils.writeTOfileAndActiveClear(PROJECT_LOG,
						DateFormat.format("yyyy-MM-dd HH:mm:ss", System.currentTimeMillis()) + "V<" + tag + ">---" + msg);
        }	
	}

	public static void i(String tag, String msg, Throwable t)
	{
		checkBetaOrLine();
		if (V_DEBUG && msg != null)
		{
			Log.i(tag, msg, t);
		}
			
    }
	
	public static void i_write(String tag, String msg, Throwable t)
	{
		checkBetaOrLine();
		if (V_DEBUG && msg != null)
		{
			Log.i(tag, msg, t);
			FileUtils.writeTOfileAndActiveClear(PROJECT_LOG,
					DateFormat.format("yyyy-MM-dd HH:mm:ss", System.currentTimeMillis()) + "Vt<" + tag + ">---" + msg);
		}
			
	}
	
	public static void e(String tag, String msg)
	{
		checkBetaOrLine();
		if (V_DEBUG && msg != null)
		{
			Log.e(tag, msg);
		}
			
	}
	
	public static void e_write(String tag, String msg)
	{
		checkBetaOrLine();
		if (V_DEBUG && msg != null)
		{
			Log.e(tag, msg);
			FileUtils.writeTOfileAndActiveClear(PROJECT_LOG,
						DateFormat.format("yyyy-MM-dd HH:mm:ss", System.currentTimeMillis()) + "V<" + tag + ">---" + msg);
        }	
	}
	

	/**
	 * 
	 * @param tag
	 * @param logMsg
	 */
	public static void writeForOTA(String tag , String logMsg, String logName)
	{
		checkBetaOrLine();
		if (V_DEBUG)
		{
			long curTimeMillis = System.currentTimeMillis();
			StringBuilder stringBuilder = new StringBuilder();
			stringBuilder.append(DateFormat.format("yyyy-MM-dd HH:mm:ss:", curTimeMillis)).append((curTimeMillis + "").substring(10, 13)).append("\t")
			             .append("< ").append(tag).append(" >").append("\t")
			             .append(logMsg).append("\t").append("\n");
			FileUtils.writeTOfileAndActiveClear(logName,stringBuilder.toString());
        }	
	}

	/**
	 *
	 * @param tag
	 * @param logMsg
	 */
	public static void writeForLOG(String tag , String logMsg, String logName)
	{
		checkBetaOrLine();
		if (V_DEBUG)
		{
			long curTimeMillis = System.currentTimeMillis();
			StringBuilder stringBuilder = new StringBuilder();
			stringBuilder.append(DateFormat.format("yyyy-MM-dd HH:mm:ss:", curTimeMillis)).append((curTimeMillis + "").substring(10, 13)).append("\t")
					.append("< ").append(tag).append(" >").append("\t")
					.append(logMsg).append("\t").append("\n");
			FileUtils.writeTOfileAndActiveClear(logName,stringBuilder.toString());
		}
	}

	public static String todayName = String.valueOf(DateFormat.format("yyyy-MM-dd", System.currentTimeMillis()));
	private static HandlerThread handlerThread;
	private static Handler fileHandler;
	private static  File currentFile;
	public static void initLogFile(String name) {
		todayName = name;
		if (OtaLog.isWriteFile){
			if (!TextUtils.isEmpty(OtaLog.sLogPath)) {
				String logName = OtaLog.sLogPath + "/" + todayName + ".txt";
				File file = new File(logName);
				if (!file.exists()) {
					try {
						file.createNewFile();
					} catch (IOException e) {
					}
				}
				currentFile = file;
				handlerThread = new HandlerThread("OtaLog" + todayName);
				handlerThread.start();
				fileHandler = new Handler(handlerThread.getLooper());
			}
		}
	}

	public static void releaseLogFile() {
		if (handlerThread != null && fileHandler != null) {
			fileHandler.postDelayed(() -> {
				currentFile = null;
				if (handlerThread != null) handlerThread.quit();
				handlerThread = null;
				fileHandler = null;
			}, 2000);
		}
	}


	public static void writeLog(String tag, String logMsg) {
		if (OtaLog.isWriteFile) {
			long curTimeMillis = System.currentTimeMillis();
			StringBuilder stringBuilder = new StringBuilder();
			stringBuilder.append(DateFormat.format("yyyy-MM-dd HH:mm:ss:", curTimeMillis)).append((curTimeMillis + "").substring(10, 13)).append("\t")
					.append("< ").append(tag).append(" >").append("\t")
					.append(logMsg).append("\t").append("\n");
			if (handlerThread != null) {
				writeToFile(stringBuilder.toString());
//				FileUtils.writeToFile(logName, stringBuilder.toString());
			}
		}
	}

	private static void writeToFile(String context) {
		try {
			if (fileHandler != null) {
				fileHandler.post(() -> {
					if (currentFile == null) return;
					BufferedWriter bw = null;
					try {
						bw = new BufferedWriter(new FileWriter(currentFile, true));
						bw.write(context);
					} catch (IOException e) {
						e.printStackTrace();
					} finally {
						try {
							if (bw != null) {
								bw.close();
							}
						} catch (IOException e) {
							e.printStackTrace();
						}
					}
				});
			}
		} catch (Exception e) {
		}
	}

	/**
	 *
	 * @param tag
	 * @param logMsg
	 */
	public static void writeComm(String tag , String fileName , String logMsg)
	{
		checkBetaOrLine();
		if (true)
		{
			StringBuilder stringBuilder = new StringBuilder();
			stringBuilder.append(DateFormat.format("yyyy-MM-dd HH:mm:ss", System.currentTimeMillis())).append("\t")
					.append("< ").append(tag).append(" >").append("\t")
					.append(logMsg).append("\t").append("\n");
			Log.e(tag, stringBuilder.toString());
			FileUtils.writeTOfileAndActiveClear(fileName,stringBuilder.toString());
		}
	}

	/**
	 *
	 * @param tag
	 * @param logMsg
	 */
	public static void writeForOTAStatic(String tag , String logMsg)
	{
		checkBetaOrLine();
		if (V_DEBUG)
		{
			StringBuilder stringBuilder = new StringBuilder();
			stringBuilder.append(DateFormat.format("yyyy-MM-dd HH:mm:ss", System.currentTimeMillis())).append("\t")
					.append("< ").append(tag).append(" >").append("\t")
					.append(logMsg).append("\t").append("\n");
			Log.e(tag, stringBuilder.toString());
			FileUtils.writeTOfileAndActiveClear(FileUtils.OTA_STATIC,stringBuilder.toString());
		}
	}

	public static void e(String tag, String msg, Throwable t)
	{
		checkBetaOrLine();
		if (V_DEBUG && msg != null)
		{
			Log.e(tag, msg, t);
		}
			
    }
	
	public static void e_write(String tag, String msg, Throwable t)
	{
		checkBetaOrLine();
		if (V_DEBUG && msg != null)
		{
			Log.e(tag, msg, t);
			FileUtils.writeTOfileAndActiveClear(PROJECT_LOG,
					DateFormat.format("yyyy-MM-dd HH:mm:ss", System.currentTimeMillis()) + "Vt<" + tag + ">---" + msg);
		}
			
	}
	
	public static void d(String tag, String msg)
	{
		checkBetaOrLine();
		if (V_DEBUG && msg != null)
		{
			Log.d(tag, msg);
		}
			
	}
	
	public static void d_write(String tag, String msg)
	{
		checkBetaOrLine();
		if (V_DEBUG && msg != null)
		{
			Log.d(tag, msg);
			FileUtils.writeTOfileAndActiveClear(PROJECT_LOG,
						DateFormat.format("yyyy-MM-dd HH:mm:ss", System.currentTimeMillis()) + "V<" + tag + ">---" + msg);
        }	
	}

	public static void d(String tag, String msg, Throwable t)
	{
		checkBetaOrLine();
		if (V_DEBUG && msg != null)
		{
			Log.d(tag, msg, t);
		}
			
    }
	
	public static void d_write(String tag, String msg, Throwable t)
	{
		checkBetaOrLine();
		if (V_DEBUG && msg != null)
		{
			Log.d(tag, msg, t);
			FileUtils.writeTOfileAndActiveClear(PROJECT_LOG,
					DateFormat.format("yyyy-MM-dd HH:mm:ss", System.currentTimeMillis()) + "Vt<" + tag + ">---" + msg);
		}
			
	}
	/**
	 * e 转 String
	 * @param ex
	 * @return
	 */
	public static String exToString(Exception ex){
		Writer writer = new StringWriter();
        PrintWriter printWriter = new PrintWriter(writer);
        ex.printStackTrace(printWriter);      
        Throwable cause = ex.getCause();
        while (cause != null) {      
            cause.printStackTrace(printWriter);      
            cause = cause.getCause();      
        }      
        printWriter.close();      
        String result = writer.toString();
        return result;
	}
}
